
(function(){

  var event = Basis.EventObject.createEvent;

  function getHash(){
    return location.hash ? location.hash.substr(1) : '';
  }

  function processHash(){
    var hash = getHash();
    if (hash !== lastHash)
    {
      //console.log('process hash: ', hash);
      lastHash = hash;

      var parts = hash.split(/:/);
      var context = parts[0] || '';
      var target = parts[1] || '';

      if (cur.context !== context)
      {
        if (context && !App.Type.resolveBem(context))
        {
          updateHash(context = '', target);
        }

        cur.context = context;
        App.UrlResolver.event_contextChanged(context);
      }

      if (cur.target !== target)
      {
        cur.target = target;
        App.UrlResolver.event_targetChanged(target);
      }

      App.UrlResolver.event_hashChanged(hash);

      return true;
    }
  }

  function updateHash(context, target){
    location.hash = context + (target ? ':' + target : '');
  }

  var hashChangeEventSupport = 'onhashchange' in window;
  var lastHash = '';
  var cur = {
    context: null, 
    target: ''
  };

  Basis.Event.onLoad(function(){
    if (!processHash())
    {
      App.UrlResolver.event_contextChanged(cur.context || '');
      App.UrlResolver.event_targetChanged(cur.target);
      App.Component.Console.focus();
    }

    if ('onhashchange' in window)
      Basis.Event.addHandler(window, 'hashchange', processHash);
    else
      setInterval(processHash, 25);
  });

  App.UrlResolver = new Basis.EventObject({
    event_hashChanged: event('hashChanged', 'hash'),
    event_contextChanged: event('contextChanged', 'location'),
    event_targetChanged: event('targetChanged', 'target'),
    setTarget: function(target){
      updateHash(cur.context || '', target || '');
    },
    setContext: function(context){
      updateHash(context || '', cur.target);
    }
  });

})();